package com.qf.utils;

import com.qf.service.UserService;
import com.qf.service.impl.UserServiceImpl;
import com.qf.service.impl.UserServiceImpl2;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Properties;

/**
 * jdk的动态代理，代理的目标对象，必须是先接口 -- jdk的动态代理只能基于接口
 *      为什么： XxxProxy extends Proxy implements Xxx,Yyy
 */
public class BeanFactory {

    public static Object getBean(String beanId)  {

        try {
            Properties properties = new Properties();
            properties.load(BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"));

            String className = properties.getProperty(beanId);

            //返回一个功能增强后的对象 -- 动态代理
            //原始对象(目标对象)
            Object obj = Class.forName(className).newInstance();

            //返回的是代理对象--对目标对象的功能进行增强
            ClassLoader cl = obj.getClass().getClassLoader();
            Class<?>[] interfaces = obj.getClass().getInterfaces();

            InvocationHandler invoker = new InvocationHandler() {
                //调用代理对象的任何方法，最终都是在执行这个invoke方法

                /**
                 * Object proxy 就是当前的代理对象 (基本不用)
                 * Method method 当前代理对象调用的那个方法
                 * Object[] args 当前代理对象调用的那个方法的参数
                 *
                 * 需求：当执行代理对象任何方法时，我需要调用目标对象的同名方法
                 *      代理对象.findAll ---> 目标对象.findAll();
                 *      代理对象.findById(5) ---> 目标对象.findById(5);
                 */
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                    System.out.println("--------------------" + method);
//                    System.out.println("--------------------" + Arrays.asList(args));

                    //判断一下当前调用的是不是find相关的方法。如果是，增强
        /*            String methodName = method.getName();
                    if (methodName.startsWith("find")){
                        System.out.println("查询缓存...");
                    }*/

                    Object invoke = method.invoke(obj, args);

                    //增强
                    return invoke;
                }
            };

            return Proxy.newProxyInstance(cl,interfaces,invoker);
        }catch (Exception e){
            e.printStackTrace();
        }

        return null;
    }
}
